package com.rpcdemo.proxy;

import com.rpcdemo.rpc.Dispatcher;
import com.rpcdemo.rpc.protocol.MyContent;
import com.rpcdemo.rpc.transport.ClientFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.CompletableFuture;

public class MyProxy {

    public static <T> T proxyGet(Class<T> interfaceClazz) {

        ClassLoader classLoader = interfaceClazz.getClassLoader();
        Class<?>[] interfaces = {interfaceClazz};

        Dispatcher dispatcher = Dispatcher.getDispatcher();

        T o = (T) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                Object impl = dispatcher.get(interfaceClazz.getName());

                Object res = null;
                if (impl != null) {
                    System.out.println("FC CALL.....");
                    Class<?> implClass = impl.getClass();
                    try {
                        Method methodName = implClass.getMethod(method.getName(), method.getParameterTypes());
                        res = methodName.invoke(impl, args);
                    } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                        e.printStackTrace();
                    }
                } else {

                    String methodName = method.getName();
                    Class<?>[] parameterTypes = method.getParameterTypes();

                    MyContent content = new MyContent();
                    content.setArgs(args);
                    content.setMethodName(methodName);
                    content.setName(interfaceClazz.getName());
                    content.setParameterTypes(parameterTypes);

                    CompletableFuture<Object> transport = ClientFactory.getFactory().transport(content);

                    res = transport.get();

                }

                return res;
            }
        });

        return o;
    }
}
